package session;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.Arrays;

import map.MapData;

import org.apache.commons.lang3.ArrayUtils;

import data.*;

//import map.MapData;

public class Session {
	
	InetAddress address;
	private DatagramSocket socket;
	private QueueThread send;
	private boolean terminated = false;
	//Std Input
	private BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
	private String input;
	
	public Session() {
		connect();
	}
	
	private void connect() {
		try {
			//Create Client Socket and connect
			socket = new DatagramSocket();
			address = InetAddress.getByName("5.209.53.193");
			socket.connect(address,7777);
			socket.setSoTimeout(15);
			//Start Queue Thread
			send = new QueueThread(this);
			
//			Handshake & Authentication
//			String username, password;
//			System.out.print("Name: ");
//			username = stdin.readLine();
//			System.out.print("Passwort: ");
//			password= stdin.readLine();
			Auth auth = new Auth("kevin", "iamkevin");
			send(auth);
			//System.out.println("UDP Handshake successfully completed");
			send.start();
			//Test MapData.request;
			this.send(MapData.request(1));
			
			while(send.sendth.isAlive()){
				input=stdin.readLine();
				if(input.equals("") || input==null) {
					this.terminate();
					break;
				}
				else {
					this.send(new Message(input));
				}
			}
			stdin.close();
			
		} catch (SocketException e) {
			System.err.println("Could not create Datagram Socket");
			e.printStackTrace();
		} catch (UnknownHostException e) {
			System.err.println("Could not find Host");
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("Error while performing Callback");
			e.printStackTrace();
		}
	}
	
	
	public void sendudp(byte[] data) throws IOException {
		DatagramPacket packetSent = new DatagramPacket(data, data.length);
		socket.send(packetSent);
	}
	
	public byte[] recvudp() throws IOException {
		byte[] bfReceive = new byte[1024];
		DatagramPacket packetReceived = new DatagramPacket(bfReceive ,bfReceive.length);
		
		try {
			socket.receive(packetReceived);
			//Get Bytes
			byte[] bytesReceived = packetReceived.getData();
			bytesReceived = Arrays.copyOf(bytesReceived, packetReceived.getLength());
			//Handle Packets
			DataHandler.handle(bytesReceived);
	        //System.out.println("Received " + packetReceived.getLength() +" Bytes: "+foo);

		} catch (SocketTimeoutException e) {
			//System.err.println("Socket Timeout");
		}
		
		
		
		return null;
	}
	
	public void send(Data data) {
		//System.out.println("Send");
		send.putsend(data);
	}
	
	public void close() {
		try {
			if(send != null) {
				send.sendth.join();
				send.recvth.join();
			}
			System.out.println("Session closed");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		socket.close();
		System.out.println("Closed Connection");
	}
	
	public boolean terminated() {
		return terminated;
	}
	public void terminate() {
		//System.out.println("Quit");
		terminated = true;
	}
	
	
	
	
	
	
//	public String callback(byte[] data) throws IOException {
//		byte[] bfSend = new byte[1024];
//		byte[] bfReceive = new byte[1024];
//		//bfSend = string.getBytes();
//		bfSend=data;
//		DatagramPacket packetSent = new DatagramPacket(bfSend, bfSend.length);
//		DatagramPacket packetReceived = new DatagramPacket(bfReceive ,bfReceive.length);
//        
//		socket.send(packetSent);
//		socket.receive(packetReceived);
//		
//		//get Byte Array
//		byte[]bytesReceived = packetReceived.getData();
//		bytesReceived = Arrays.copyOf(bytesReceived, packetReceived.getLength());
//		//Output as String
//        String foo = new String(ArrayUtils.subarray(bytesReceived,3,bytesReceived.length));
//        System.out.println("Received " + packetReceived.getLength() +" Bytes: "+foo);
//		//Output as Bytes
//		for(byte bite:bytesReceived) {
//			System.out.print(bite+" ");
//		}
//		System.out.println();
//		
//		//Return String representation of Data received
//        return foo;
//	}
	
	
	
}
